package com.ruoyi.prod.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.ruoyi.prod.entity.dto.ProdAssetSummary;
import com.ruoyi.prod.entity.po.ProdAsset;
import com.ruoyi.prod.entity.po.ProdPurchase;
import com.ruoyi.prod.entity.query.ProdAssetCondition;
import com.ruoyi.prod.entity.query.ProdPurchaseCondition;
import com.ruoyi.prod.enums.AssetState;
import com.ruoyi.prod.enums.LogModuleEnum;
import com.ruoyi.prod.enums.LogTypeEnum;
import com.ruoyi.prod.enums.OddTypeEnum;
import com.ruoyi.prod.mapper.ProdAssetMapper;
import com.ruoyi.prod.service.BaseLogService;
import com.ruoyi.prod.service.ProdAssetService;
import com.ruoyi.prod.service.ProdPurchaseService;
import com.ruoyi.prod.service.ProdUseApplyItemService;
import com.ruoyi.prod.util.IsUtil;
import com.ruoyi.prod.util.OddUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.LinkedList;
import java.util.List;

/**
 * <p>
 * 资产管理-资产台账 服务实现类
 * </p>
 *
 * @author 强子初
 * @since 2023-02-18
 */
@Service
public class ProdAssetServiceImpl extends ServiceImpl<ProdAssetMapper, ProdAsset> implements ProdAssetService {

    @Autowired
    ProdPurchaseService planService;

    @Autowired
    ProdUseApplyItemService useApplyItemService;

    @Autowired
    BaseLogService logService;

    @Override
    public String getOdd() {
        return OddUtil.generate(OddTypeEnum.ASSET.getCode());
    }

    @Override
    public List<ProdAsset> list(ProdAsset condition) {
        return this.list(this.getWrapper(condition));
    }

    @Override
    public Page<ProdAsset> page(ProdAsset condition) {
        Page<ProdAsset> page = PageHelper.startPage(condition.getPageNum(), condition.getPageSize());
        this.list(condition);
        return page;
    }

    @Override
    public Page<ProdAssetSummary> summary(ProdAssetCondition condition) {
        Page<ProdAssetSummary> page = PageHelper.startPage(condition.getPageNum(), condition.getPageSize());
        baseMapper.summary(condition);
        return page;
    }

    @Override
    public List<ProdAsset> save(ProdPurchaseCondition condition) {

        ProdPurchase plan = planService.getById(condition.getId());

        List<ProdAsset> list = new LinkedList<>();

        for (int i = 0; i < condition.getFinishNumber(); i++) {
            ProdAsset po = new ProdAsset();
            BeanUtils.copyProperties(plan, po);
            po.setId(null);
            po.setCode(this.getOdd());
            po.setPurchaseId(plan.getId());
            po.setPurchaseOdd(plan.getOdd());
            po.setPrice(condition.getPrice());
            po.setUseLife(condition.getUseLife());
            po.setValueRate(condition.getValueRate());
            po.setAssetState(AssetState.NOT_USED);
            list.add(po);
        }
        this.saveBatch(list);
        return list;
    }

    @Override
    public void updateToAssetState(String id, AssetState newState) {
        updateToAssetState(id, this.getById(id).getAssetState(), newState);
    }

    @Override
    public void updateToAssetState(String id, AssetState oldState, AssetState newState) {
        // 使用中 转 未使用
        if (oldState == AssetState.IN_USE && newState == AssetState.NOT_USED) {
            // 删除使用记录
            useApplyItemService.deleteByAssetId(id);
        }

        // 修改资产状态
        LambdaUpdateWrapper<ProdAsset> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(ProdAsset::getAssetState, newState)
                .eq(ProdAsset::getId, id);
        this.update(wrapper);

        // 添加日志
        LogTypeEnum logType = IsUtil.getLogType(oldState, newState);
        logService.save(id, LogModuleEnum.ASSET, logType);
    }

    private LambdaQueryWrapper<ProdAsset> getWrapper(ProdAsset condition) {
        LambdaQueryWrapper<ProdAsset> wrapper = new LambdaQueryWrapper<>();

        if (condition.getAssetTypeId() != null) {
            wrapper.eq(ProdAsset::getAssetTypeId, condition.getAssetTypeId());
        }

        if (condition.getName() != null) {
            wrapper.eq(ProdAsset::getName, condition.getName());
        }

        if (condition.getModel() != null) {
            wrapper.eq(ProdAsset::getModel, condition.getModel());
        }

        if (condition.getAssetStateList() != null && condition.getAssetStateList().size() > 0)
            wrapper.in(ProdAsset::getAssetState, condition.getAssetStateList());

        if (condition.getIds() != null && condition.getIds().size() > 0)
            wrapper.in(ProdAsset::getId, condition.getIds());

        wrapper.orderByDesc(ProdAsset::getUpdateTime);
        return wrapper;
    }
}
